package phases

import (
	"github.com/pkg/errors"
	confv1beta1 "gopkg.openfuyao.cn/bkecommon/cluster/api/v1beta1"
	ctrl "sigs.k8s.io/controller-runtime"

	bkev1beta1 "gopkg.openfuyao.cn/cluster-api-provider-bke/api/v1beta1"
	"gopkg.openfuyao.cn/cluster-api-provider-bke/pkg/certs"
	"gopkg.openfuyao.cn/cluster-api-provider-bke/pkg/phaseframe"
)

const (
	EnsureCertsName confv1beta1.BKEClusterPhase = "EnsureCerts"
)

type EnsureCerts struct {
	phaseframe.BasePhase

	certsGenerator *certs.BKEKubernetesCertGenerator
}

func NewEnsureCerts(ctx *phaseframe.PhaseContext) phaseframe.Phase {
	base := phaseframe.NewBasePhase(ctx, EnsureCertsName)
	return &EnsureCerts{
		BasePhase:      base,
		certsGenerator: certs.NewKubernetesCertGenerator(ctx.Context, ctx.Client, ctx.BKECluster),
	}
}

func (e *EnsureCerts) Execute() (_ ctrl.Result, err error) {
	if err = e.certsGenerator.LookUpOrGenerate(); err != nil {
		return ctrl.Result{}, errors.Errorf("failed to generate certs, err: %v", err)
	}

	need, err := e.certsGenerator.NeedGenerate()
	if err != nil {
		return ctrl.Result{}, err
	}
	if need {
		return ctrl.Result{}, errors.Errorf("certs need generate again, err: %v", err)
	}

	return ctrl.Result{}, nil
}

func (e *EnsureCerts) NeedExecute(old *bkev1beta1.BKECluster, new *bkev1beta1.BKECluster) (needExecute bool) {
	if !e.BasePhase.DefaultNeedExecute(old, new) {
		return false
	}
	need, err := e.certsGenerator.NeedGenerate()
	if err != nil || !need {
		return false
	}
	e.SetStatus(bkev1beta1.PhaseWaiting)
	return true
}
